# arcflowd.mod    
# by Yu Liu, 03/2001.   Based on survB.mod
# Arc-flow model for spare capacity allocation
# for failure dependent cases.

set NODES;
set LINKS within {i1 in NODES, NODES diff {i1}};
set FLOWS := {i1 in NODES, NODES diff {i1}};
param M {FLOWS} integer default 1 >=0; 

param R {NODES,LINKS} integer default 0 >= -1 <= 1;
param D {FLOWS,NODES} integer default 0 >= -1 <= 1;
param oR {NODES,LINKS} binary default 0;
param dR {NODES,LINKS} binary default 0;
param oD {FLOWS,NODES} binary default 0;
param dD {FLOWS,NODES} binary default 0;

param stubr binary default 0;

param A {FLOWS, LINKS} binary default 0;
param w {LINKS} integer default 0;
var B {LINKS, FLOWS, LINKS} binary default 0;
var C {LINKS, LINKS} integer default 0;
var s {LINKS} integer default 0;

minimize work_cost:  sum {(i1,i2) in LINKS} w[i1,i2];
#s.t. mass_ba {(r1,r2) in FLOWS, n1 in NODES}:
#  sum {(i1,i2) in LINKS} A[r1,r2,i1,i2]*R[n1,i1,i2] 
#      = D[r1,r2,n1];
#s.t. cap_aggr {(i1,i2) in LINKS}:
#  w[i1,i2] = sum{(r1,r2) in FLOWS} A[r1,r2,i1,i2];
#problem find_work:  work_cost,  mass_ba, cap_aggr, A, w;

minimize spare_cost: sum {(i1,i2) in LINKS} s[i1,i2];

s.t. mass_ba2 {(r1,r2) in FLOWS, n1 in NODES, (j1,j2) in LINKS}:
  sum {(i1,i2) in LINKS} B[j1,j2,r1,r2,i1,i2]*R[n1,i1,i2]=D[r1,r2,n1]*(A[r1,r2,j1,j2]+A[r1,r2,j2,j1]);

s.t. cap_aggr2 {(i1,i2) in LINKS, (j1,j2) in LINKS}:
  s[i1,i2] >= C[i1,i2,j1,j2];

s.t. spare_prov {(i1,i2) in LINKS, (j1,j2) in LINKS}:
  C[i1,i2,j1,j2] = sum{(r1,r2) in FLOWS} 
    M[r1,r2] * (B[j1,j2,r1,r2,i1,i2] * (A[r1,r2,j2,j1]+A[r1,r2,j1,j2]) - A[r1,r2,i1,i2] *(A[r1,r2,j1,j2]+A[r1,r2,j2,j1]) * stubr );

s.t. link_disjoint {(r1,r2) in FLOWS,(i1,i2) in LINKS,(j1,j2) in LINKS}:
  A[r1,r2,i1,i2] + B[j1,j2,r1,r2,i1,i2] <=1;

s.t. link_sym {(r1,r2) in FLOWS,(i1,i2) in LINKS,(j1,j2) in LINKS}:
  B[j1,j2,r1,r2,i1,i2] = B[j1,j2,r2,r1,i2,i1];

problem find_spare:
 spare_cost,  mass_ba2, cap_aggr2, 
 link_sym, spare_prov, link_disjoint, B, C, s;

param MaxNode integer default 5;
param MaxLink integer default 7;
param MaxFlow integer default 10;
param MaxHop integer default 6;

param t1 integer;
param t2 integer;
